﻿using Company.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Company.Core.Models
{
    /// <summary>
    /// 非托管数组基类（以数组的形式描述内存中的图像，考虑适用于2维图像、3维图像）
    /// </summary>
    public class UnmanagedArrayBase : IDisposable
    {
        /// <summary>
        /// 对象指针
        /// </summary>
        public IntPtr IntPtr { get; private set; }

        /// <summary>
        /// 数组总长度个数
        /// </summary>
        public long Length { get; }

        /// <summary>
        /// 单个元素占用内存大小
        /// </summary>
        public int ItemSize { get; }

        /// <summary>
        /// 数组占用内存总大小
        /// </summary>
        public long Size => Length * ItemSize;

        /// <summary>
        /// 实例化非托管数组基类
        /// </summary>
        /// <param name="length">数组总长度个数</param>
        /// <param name="itemSize">单个元素占用内存大小</param>
        /// <param name="isResetMemory">将分配的内存所有字节设置为 0（防止脏数据）</param>
        /// <exception cref="ArgumentException"></exception>
        public UnmanagedArrayBase(long length, int itemSize, bool isResetMemory = true)
        {
            if (length <= 0) throw new ArgumentException($"{nameof(length)} 不能小于零");
            if (itemSize <= 0) throw new ArgumentException($"{nameof(itemSize)} 不能小于零");
            Length = length;
            ItemSize = itemSize;
            IntPtr = Marshal.AllocHGlobal(new IntPtr(Size)); // 分配内存
            if (isResetMemory)
            {
                MemoryHelper.ZeroMemory(IntPtr, Size); // 内存清零，防止脏数据
            }
        }

        ~UnmanagedArrayBase()
        {
            Dispose(false); // 避免在GC回收时操作可能已失效的托管对象，仅处理非托管资源。
        }

        public void Dispose()
        {
            Dispose(true); // 用户显示调用，确定性释放所有资源（托管+非托管）
            GC.SuppressFinalize(this); // 阻止GC重复执行析构函数
        }

        private bool _disposed = false;
        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // 释放托管资源

                }

                // 释放非托管资源
                if (this.IntPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(this.IntPtr);
                    this.IntPtr = IntPtr.Zero;
                }

                _disposed = true;
            }
        }
    }
}
